home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
graphics
/
raymovi2.arc
/
FIND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-21
|
3KB
|
158 lines
#include <math.h>
#include "rtd.h"
#include "extern.h"
/* find where a ray leaves a sphere */
double findo (m, s)
struct mat *m;
struct sphere *s;
{
struct vector foops;
double t;
/* foops is the rotated vector for the center of the sphere
with respect to the beginning of the ray */
mt_vec (&foops, m, &(s->cent));
/* find out if the center of the sphere is within range.
(it should be for this...)*/
t = s->rad * s->rad - foops.y * foops.y - foops.z * foops.z;
/*return distance from original entry. we can find the point
when we get out*/
if (t > 0)
t = foops.x + sqrt (t);
else
t = 0;
return (t);
}
/* find where a ray next hits (enters or exits) a sphere */
double findx (m, s)
struct mat *m;
struct sphere *s;
{
struct vector foops;
double t;
/* foops is the rotated vector for the center of the sphere
with respect to the beginning of the ray */
mt_vec (&foops, m, &s->cent);
t = s->rad*s->rad - foops.y*foops.y - foops.z*foops.z;
if (t < 0)
t = HUGE; /* doesn't touch, return flag */
else
{ t = sqrt(t);
if (foops.x > t + EPSILON)
t = foops.x - t; /* return distance to entering */
else if (foops.x > - t + EPSILON)
t = -foops.x - t; /* return minus distance to exiting */
else
t = HUGE;
}
return (t);
}
/* see above. the only difference is that
the value returned is foops.x - sqrt(t) */
double find (m, s)
struct mat *m;
struct sphere *s;
{
struct vector foops;
double t;
mt_vec (&foops, m, &(s->cent));
t = s->rad * s->rad - foops.y * foops.y - foops.z * foops.z;
if (t > 0)
t = foops.x - sqrt (t);
else
t = 0;
return (t);
}
/* returns value telling how much a sphere
is occluding the light source */
double finds (m, s)
struct mat *m;
struct sphere *s;
{
struct vector foops;
double t;
mt_vec (&foops, m, &(s->cent));
t = s->rad - sqrt (foops.y * foops.y + foops.z * foops.z);
if (t > 0)
t = t / foops.x;
else
t = 0;
return (t); /* radians between ray and edge of intersecting sphere*/
}
/* gets amount of diffuse light hitting a point */
float shadow (p, rd, gn, blu)
struct vector *p;
double *rd, *gn, *blu;
{
struct mat trans;
struct sphere ss;
struct vector d;
int c,
i;
double l,
k,
x,
y,
z,
finds ();
l = 0.0;
c = -1;
sv (&d, &(ls.cent), p);
vecl (&d); /*!!*/
vexzl (&d); /*!!*/
mt (&(d), &trans);
/* get maximum obscurment */
for (i = 0; i < nob; i++) {
ss.rad = bl[i].s.rad;
sv (&(ss.cent), &(bl[i].s.cent), p);
if ((k = finds (&trans, &ss)) > l) {
c = i;
l = k;
}
}
if (c == -1)
k = 255.0;
else {
k = 1.0 - l * d.l / ls.rad;
if (k < 0.0) /* l = angle to move to get ray out of sphere*/
k = 0.0; /* d.l/ls.rad = 1/angle light source subtends */
else
k *= 255.0;
}
*rd = *gn = *blu = k; /* all colors the same for now */
}